Skip to content

feat(pai): separate pai command from opencode#104

Merged
Steffen025 merged 5 commits intoSteffen025:mainfrom
eddovandenboom:pai-wrapper-script
Apr 11, 2026
Merged

feat(pai): separate pai command from opencode#104
Steffen025 merged 5 commits intoSteffen025:mainfrom
eddovandenboom:pai-wrapper-script

Conversation

@eddovandenboom
Copy link
Copy Markdown
Contributor

@eddovandenboom eddovandenboom commented Apr 8, 2026

Summary

Separates the "pai" command from "opencode" command with proper context loading and fixes content loading for "pai".

Changes

  • Separate context loading for pai vs opencode commands
  • Fix content loading for "pai" command
  • Update .gitignore for .opencode/PAI/USER/*

Summary by CodeRabbit

  • Chores
    • Updated repository configuration for improved directory structure management.
    • Enhanced plugin bootstrap loading to resolve paths independently of working directory.
    • Added environment-based activation control for feature initialization.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 8, 2026

Warning

Rate limit exceeded

@Steffen025 has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 10 minutes and 34 seconds before requesting another review.

Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 10 minutes and 34 seconds.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 0ae068e0-579b-4439-a6e6-cea4f7985452

📥 Commits

Reviewing files that changed from the base of the PR and between aeac334 and b7fa559.

📒 Files selected for processing (3)
  • .gitignore
  • .opencode/PAI/Tools/pai.ts
  • .opencode/plugins/pai-unified.ts
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@eddovandenboom eddovandenboom changed the base branch from dev to main April 8, 2026 23:49
.opencode/package.json declares "type": "module", which means the
CommonJS globals __dirname / __filename are not defined at runtime in
.opencode/plugins/pai-unified.ts. The original fix introduced a
ReferenceError that would trigger the first time loadMinimalBootstrap()
was called after a user ran the 'pai' command.

Replaced with the ESM-idiomatic pattern:

    import { fileURLToPath } from 'node:url';
    const PLUGIN_DIR = path.dirname(fileURLToPath(import.meta.url));

PLUGIN_DIR is now resolved once at module load and reused inside
loadMinimalBootstrap(). Same intent as the original fix (resolve PAI
dir relative to plugin location, not cwd) — just compatible with
the ESM module system.

Co-authored-by: eddovandenboom <eddovandenboom@users.noreply.github.com>
@Steffen025
Copy link
Copy Markdown
Owner

Hey @eddovandenboom — thank you so much for this contribution! 🙏

This PR does two genuinely valuable things:

  1. pai vs opencode separation — gating the context injection behind PAI_ENABLED=1 (via the pai wrapper setting the env var) so plain opencode can launch without PAI taking over is exactly the kind of UX refinement v3.0 needs. It makes the two commands behave predictably and gives users a clean way to "just run vanilla opencode" from a PAI install.

  2. The loadMinimalBootstrap() cwd → plugin-relative fix — this was an actual bug. The old code resolved PAI/ relative to process.cwd(), which broke the moment a user launched opencode from any directory other than the PAI install root. Resolving relative to the plugin file is the correct approach.

One adjustment I pushed

I hope you don't mind — I pushed a small fix on top of your branch (commit aeac334, with you as co-author). The original const pluginDir = path.dirname(__filename) would have thrown ReferenceError: __filename is not defined at runtime because .opencode/package.json declares "type": "module", and __filename/__dirname are CommonJS-only globals — they don't exist in ESM.

The ESM-idiomatic replacement is:

import { fileURLToPath } from "node:url";

const PLUGIN_DIR = path.dirname(fileURLToPath(import.meta.url));

I resolved PLUGIN_DIR once at module-load time and reused it inside loadMinimalBootstrap(), same intent as your fix — just compatible with the module system. I verified it bundles cleanly via bun build --target=bun and that grep '__filename' returns only comments explaining the workaround.

Your commit is preserved intact — my fix is a follow-up commit on top with Co-authored-by: eddovandenboom in the footer.

Context: PR #107 is about to ship

While we wait for CodeRabbit's review of my follow-up commit, a heads up: we're preparing to ship PAI-OpenCode v3.0 very soon (targeting tomorrow). The big piece of v3.0 is PR #107 — the "Vanilla OpenCode Migration" that drops the custom Steffen025/opencode fork entirely and moves to vanilla OpenCode from opencode.ai. Your PR complements that perfectly: once users are on vanilla, they need a clean way to launch opencode with or without PAI context, which is exactly what your PAI_ENABLED gate provides.

Your changes don't conflict with #107 (different files), so after CodeRabbit green-lights the follow-up commit here, this PR can merge independently and ship alongside #107 in v3.0.

Credit

You'll be credited in the v3.0 CHANGELOG release notes as one of two community contributors who made this release possible (@ktneely is the other — he fixed the stale OpenCode Zen model roster in #103, integrated into #107). Both contributions landed in exactly the right week. 🎉

If you'd like a different attribution name or link (e.g., your site, social handle), let me know and I'll update the CHANGELOG entry before we tag v3.0.

Thanks again — community PRs like this one, where a contributor identifies a real UX gap and ships a clean fix for it, are exactly what healthy OSS looks like. 🚀

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.gitignore:
- Around line 19-21: The .gitignore currently includes an unnecessary exception
for "!.opencode/PAI/USER/.gitkeep" which does not exist; remove that line so the
block keeps only the ignore for ".opencode/PAI/USER/*" and the README exception
"!.opencode/PAI/USER/README.md". Update the .gitignore by deleting the
"!.opencode/PAI/USER/.gitkeep" entry (leaving ".opencode/PAI/USER/*" and
"!.opencode/PAI/USER/README.md") and re-evaluate whether any subdirectories
(ACTIONS, BUSINESS, FLOWS, etc.) need their own keep files if they should be
tracked.

In @.opencode/PAI/Tools/pai.ts:
- Around line 462-466: The spawn call that sets PAI_ENABLED for cmdLaunch only
causes cmdPrompt to run without the PAI context gate; update cmdPrompt's spawn
(or the shared launcher) to include env: { ...process.env, PAI_ENABLED: "1" } so
both cmdLaunch and cmdPrompt run with the plugin bootstrap/context injection
enabled (alternatively factor the spawn options into a shared helper used by
cmdLaunch and cmdPrompt to ensure the PAI_ENABLED env var is always set).

In @.opencode/plugins/pai-unified.ts:
- Around line 394-400: The gating currently treats any non-empty PAI_ENABLED
value as enabled inside the experimental.chat.system.transform handler; change
the condition to explicitly check for the wrapper contract value
(process.env.PAI_ENABLED !== "1") so only "1" enables PAI context, and update
the log message if needed to reflect the explicit check; locate the check inside
the experimental.chat.system.transform function and replace the loose truthy
test with the explicit comparison.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 9e1c72c8-a658-4bf1-983c-823f4e8aa6a6

📥 Commits

Reviewing files that changed from the base of the PR and between 372a751 and aeac334.

📒 Files selected for processing (3)
  • .gitignore
  • .opencode/PAI/Tools/pai.ts
  • .opencode/plugins/pai-unified.ts

Steffen025 and others added 2 commits April 12, 2026 01:38
…ENABLED check

Three findings from CodeRabbit, all verified and fixed.

- .gitignore: remove the spurious '!.opencode/PAI/USER/.gitkeep' exception.
  The .gitkeep file does not exist in PAI/USER/ (only README.md and several
  real directories like ACTIONS, BUSINESS, FLOWS, etc.). The exception was
  modelled on the .opencode/USER/ block which does ship a .gitkeep, but
  PAI/USER/ does not. The block is now:
    .opencode/PAI/USER/*
    !.opencode/PAI/USER/README.md

- .opencode/PAI/Tools/pai.ts: cmdPrompt was missing PAI_ENABLED: '1' in its
  spawn env, so one-shot headless prompts (e.g. 'pai -p "..."') ran without
  the plugin injecting PAI context. Added the same env flag that cmdLaunch
  already had so both interactive and prompt modes load the full PAI bootstrap.

- .opencode/plugins/pai-unified.ts: the PAI_ENABLED gate used a loose truthy
  check (!process.env.PAI_ENABLED) which would enable context injection for
  any non-empty value, including 'PAI_ENABLED=0' or 'PAI_ENABLED=false'.
  Replaced with an explicit strict equality check (process.env.PAI_ENABLED
  !== '1') that only activates for exactly the string '1', matching the
  contract set by the pai wrapper. Updated the log message accordingly.

Co-authored-by: eddovandenboom <eddovandenboom@users.noreply.github.com>
@Steffen025 Steffen025 marked this pull request as ready for review April 11, 2026 23:41
@Steffen025 Steffen025 merged commit 6f1eab3 into Steffen025:main Apr 11, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants